/**
 * TetrisPlayerController - 
 * 
 * @extends PlayerController
 * 
 * @author
 * @version 2010.10.24
 */

class TetrisPlayerController extends PlayerController;

var Board        board;
var Vector       poolLocation;
var array<Block> blockPool;
var int          nextFreeBlock;



/**
 * PostBeginPlay -
 * 
 * @note Center of platform for blocks is at (16, -128, 120)
 * 
 * @author
 * @version 2010.10.24
 */
simulated function PostBeginPlay() {
	board = new class'Board';
	board.setUp();

	poolLocation.X = 0;
	poolLocation.Y = 0;
	poolLocation.Z = -512;

	nextFreeBlock = populateBlockPool();

	SetTimer(1.00, true);
}

/**
 * DrawHUD - 
 * 
 * @author
 * @version 2010.10.24
 */
function DrawHUD(HUD H) {
	super.DrawHUD(H);

	H.Canvas.SetDrawColor(0,255,0,255);
	// score box
	H.Canvas.SetPos((H.SizeX - 150), H.SizeY - 150);
	H.Canvas.DrawBox(60,60);
	// score text
	H.Canvas.SetPos((H.SizeX - 140), H.SizeY - 140);
	H.Canvas.Font = class'Engine'.static.GetMediumFont();
	H.Canvas.DrawText(board.score);
	// next piece box
	H.Canvas.SetPos((H.SizeX - 160), H.CenterY/4);
	H.Canvas.DrawBox(160,160);
	// next piece
	H.Canvas.SetPos((H.SizeX - 160), H.CenterY/4);
	drawPiece(H);
}

function drawPiece(HUD H){
	local int i,j;
	local Piece nextPiece;
	local TwoDArray blocks;

	nextPiece = board.nextPiece;
	blocks = nextPiece.getCurrentBlockArray();
	
	for(i = 0; i < 4; i++){
		for(j = 0; j < 4; j++){
			H.Canvas.SetPos((H.SizeX - 160) + j*40, H.CenterY/4 + i*40);
			H.Canvas.DrawBox(40,40);
			if(blocks.get(i,j) == 1){
				H.Canvas.SetDrawColor(255,0,0,255);
				H.Canvas.DrawRect(40,40);
				H.Canvas.SetDrawColor(0,255,0,255);
			}
		}
	}	
}

/**
 * Timer - 
 * 
 * @author
 * @version 2010.10.24
 */
event Timer() {	
	clearBoard();
	board.dropActivePiece();
	drawBoard();
	
}

/**
 * populateBlockPool - spawns the maximum number of blocks
 * that can be drawn at a time (i.e. number of elements in the
 * board's grid). 
	 * 
 * @return an index pointing to the end of the list
 * 
 * @author Clinton Freeman
 * @version 2010.10.24
 */
function int populateBlockPool() {
	local int   numBlocks, i;
	local Block b;

	numBlocks = board.getHeight() * board.getWidth();

	for(i = 0; i < numBlocks; i++) {
		b = createBlock();
		blockPool.AddItem(b);
	}

	return (numBlocks - 1);
}

/**
 * createBlock - creates a block actor and attaches 
 * a cube mesh to it
 * 
 * @todo loc doesn't even exist
 * @return new block actor
 * 
 * @author Clinton Freeman
 * @version 2010.10.24
 */
function Block createBlock() {
	local StaticMeshComponent cubeMesh;
	local Block               b;

	cubeMesh = new class'StaticMeshComponent';
	cubeMesh.SetStaticMesh(StaticMesh'EngineMeshes.Cube');

	b = Spawn(Class'Block',,,poolLocation,);
	b.AttachComponent(cubeMesh);
	b.SetDrawScale(0.25);


	return b;
}

/**
 * clearBoard - moves all block actors to a position not
 * visible to the player.
 * 
 * @author Clinton Freeman
 * @version 2010.10.24
 */
function clearBoard() {
	local Vector currentPos;
	local int numUsedBlocks, i;

	numUsedBlocks = blockPool.Length - nextFreeBlock;
	
	for(i = 0; i < numUsedBlocks; i++) {
		currentPos = poolLocation - blockPool[nextFreeBlock].Location;
		blockPool[nextFreeBlock++].Move(currentPos);
	}
	if(nextFreeBlock == (board.getHeight() * board.getWidth())){
		nextFreeBlock--;
	}
}

/**
 * drawBoard - iterates through the current board array and
 * if a location is filled, grabs a block from the pool
 * and moves it to the appropriate location.
 * 
 * @todo ...implement....
 * @author Clinton Freeman
 * @version 2010.10.24
 */
function drawBoard() {
	local int       row, col;
	local TwoDArray boardArray;
	local Vector    loc, delta;

	boardArray = board.getBoard();

	for(row = 0; row < board.getHeight(); row++) {
		for(col = 0; col < board.getWidth(); col++) {
			`log("row:"$row$" col:"$col$" Num:"$boardArray.get(row,col)$" nextFreeBlock:"$nextFreeBlock$" ");
			if(boardArray.get(row, col) == 1) {
				loc.X = 16;
				loc.Y = -384 + col*64;
				loc.Z = 696 - row*64;
				delta = loc - blockPool[nextFreeBlock].Location;
				
				blockPool[nextFreeBlock--].Move(delta);
			}
		}
	}
}

//Custom input handlers
exec function moveLeft()    { board.movePiece(-1); }
exec function moveRight()   { board.movePiece(1);  }
exec function rotatePiece() { board.rotateActivePiece(); }
exec function dropPiece()   { board.instantDrop(); }
exec function speedUp()     {                      }